package com.hww.v2_mtfsdk.utils.camera;

import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Build;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.hww.common.util.LogUtils;

import java.util.List;

/**
 * @author hww
 * @date 2020/11/5
 * email：
 * description：
 */
public class Camera1SurfaceView extends SurfaceView {

    private CameraCallBack cameraCallBack;
    private SurfaceHolder surfaceHolder;
    /**
     * 摄像头对象
     */
    private Camera camera;
    /**
     * 摄像ID
     */
    private int cameraID = Camera.CameraInfo.CAMERA_FACING_BACK;
    /**
     * 摄像预览界面旋转角度
     */
    private int orientation = 90;
    /**
     * 摄像头预览的宽
     */
    private int previewWidth = 640;
    /**
     * 摄像头预览的高
     */
    private int previewHeight = 480;

    private Context context;

    public Camera1SurfaceView(Context context) {
        super(context);
        this.context = context;
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(callback);
    }

    public Camera1SurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        surfaceHolder = getHolder();
        surfaceHolder.addCallback(callback);
    }

    /**
     * 初始化相关参数
     *
     * @param cameraID
     * @param orientation
     * @param cameraCallBack
     */
    public void initCameraParams(int cameraID, int orientation, CameraCallBack cameraCallBack) {
        this.cameraID = cameraID;
        this.orientation = orientation;
        this.cameraCallBack = cameraCallBack;

        surfaceHolder = getHolder();
        surfaceHolder.addCallback(callback);
    }

    /**
     * 打开摄像头并显示
     */
    public void startPreview() {
        synchronized (this) {
            try {
                LogUtils.file("camera1SurfaceView", "startPreview");
                if (null != camera) {
                    setCameraStatusFalse("camera object is not null");
                    return;
                }
                camera = Camera.open(cameraID);
                LogUtils.file("camera1SurfaceView", "openCamera  status = " + (camera != null));
                Camera.Parameters parameters = camera.getParameters();
                List<Camera.Size> previewSize = parameters.getSupportedPreviewSizes();
                LogUtils.file("camera1SurfaceView", "获取摄像头PreViewSize成功");
                if (!previewSizeStatus(previewSize)) {
                    return;
                }
                parameters.setPreviewSize(previewWidth, previewHeight);
//            if (MyApplication.dCamera.openFlash) {
//                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
//            }
//            List<String> supportedFocusModes = parameters.getSupportedFocusModes();
//            for (String mode : supportedFocusModes) {
//                Log.e("hwwFace", "focus mode : " + mode);
//            }

//            List<String> supportedSceneModes = parameters.getSupportedSceneModes();
//            for (String mode : supportedSceneModes) {
//                Log.e("hwwFace", "mode : " + mode);
//            }
                camera.setParameters(parameters);
                LogUtils.file("camera1SurfaceView", "配置摄像头相关参数成功   宽：" + previewWidth + "  高：" + previewHeight);
                try {
                    if ("ISCAN500F".equals(Build.MODEL)) {
                        parameters.setSceneMode("sports");
                        parameters.setFocusMode("infinity");
                        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
                        camera.setParameters(parameters);
                        LogUtils.file("camera1SurfaceView", "ISCAN500F设备配置模式  sports  infinity 成功");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                if (null != cameraCallBackBuffer) {
                    cameraCallBackBuffer = null;
                }
                bufferCameraCallbackSize = previewHeight * previewWidth * ImageFormat.getBitsPerPixel(parameters.getPreviewFormat()) / 8;
                cameraCallBackBuffer = new byte[bufferCameraCallbackSize];
                camera.addCallbackBuffer(cameraCallBackBuffer);
                LogUtils.file("camera1SurfaceView", "设置摄像头缓存buffer");

                camera.setDisplayOrientation(orientation);
                LogUtils.file("camera1SurfaceView", "设置摄像头 旋转角度 " + orientation);
                camera.setPreviewCallbackWithBuffer(previewCallback);
//                camera.setPreviewCallback(previewCallback);
                LogUtils.file("camera1SurfaceView", "设置摄像头  设置回调数据成功");
                camera.setPreviewDisplay(surfaceHolder);
                LogUtils.file("camera1SurfaceView", "设置摄像头  显示 surfaceHolder");
                camera.startPreview();
                LogUtils.file("camera1SurfaceView", "设置摄像头  开始显示 startPreView");
                if (null != cameraCallBack) {
                    cameraCallBack.cameraStatus(true, String.format("openCamera success  id=%s   disPlay=%s", cameraID, orientation));
                }
            } catch (Exception e) {
                setCameraStatusFalse("Error: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    /**
     * 配置摄像头参数宽高
     *
     * @param width
     * @param height
     */
    public void setPreViewParams(int width, int height) {
        this.previewWidth = width;
        this.previewHeight = height;
        LogUtils.file("camera1SurfaceView", "设置摄像头参数  宽：" + previewWidth + "   高：" + previewHeight);
    }

    private boolean previewSizeStatus(List<Camera.Size> previewSize) {
        for (Camera.Size size : previewSize) {
            if (previewWidth == size.width && previewHeight == size.height) {
                return true;
            }
        }
        setCameraStatusFalse(String.format("parameter error: Size  width:%s height:%s", previewWidth, previewHeight));
        return false;
    }

    /**
     * 关闭显示，同时释放摄像头
     */
    public void stopPreview() {
        synchronized (this) {
            LogUtils.file("camera1SurfaceView", "stopPreView()");
            if (null != camera) {
                //if (null != surfaceHolder) {
                //    surfaceHolder.removeCallback(callback);
                //}
                camera.setPreviewCallbackWithBuffer(null);
                camera.setPreviewCallback(null);
                camera.stopPreview();
                /*camera.unlock();*/
                camera.release();
                cameraCallBackBuffer = null;
                camera = null;
                LogUtils.file("camera1SurfaceView", "stopPreView()    释放成功");
            }
        }
    }

    SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            LogUtils.file("camera1SurfaceView", "SurfaceHolder.Callback   surfaceCreated  ");
            if (null != camera) {
                try {
                    camera.setPreviewDisplay(holder);
                    camera.startPreview();
                    LogUtils.file("camera1SurfaceView", "SurfaceHolder.Callback   surfaceCreated   startPreview");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                startPreview();
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            LogUtils.file("camera1SurfaceView", "SurfaceHolder.Callback   surfaceDestroyed  ");
            stopPreview();
        }
    };

    /**
     * 摄像头回调数据复用内存
     */
    private byte[] cameraCallBackBuffer;
    private int bufferCameraCallbackSize;
    Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            if (null == data) {
                cameraCallBackBuffer = new byte[bufferCameraCallbackSize];
                camera.addCallbackBuffer(cameraCallBackBuffer);
            } else {
                camera.addCallbackBuffer(data);
            }
            if (null != cameraCallBack) {
                cameraCallBack.onPreviewFrameCallBack(data, previewWidth, previewHeight, orientation);
            }
        }
    };

    /**
     * 配置回调接口{@link CameraCallBack#cameraStatus(boolean, String)}
     *
     * @param msg 描述
     */
    private void setCameraStatusFalse(String msg) {
        if (null != cameraCallBack) {
            cameraCallBack.cameraStatus(false, "cameraId:" + cameraID + "   " + msg);
        }
    }
}